// matlab注释
/*
% 利用L1Norm作为度量，构建两个样本之间距离邻接矩阵W
%	Usage:
%	W = constructW(fea,options)
%
%	fea: Rows of vectors of data points. Each row is x_i
%   options: Struct value in Matlab. The fields in options that can be set:
%                  
%           NeighborMode -  Indicates how to construct the graph. Choices
%                           are: [Default 'KNN']
%                'KNN'            -  k = 0
%                                       Complete graph
%                                    k > 0
%                                      Put an edge between two nodes if and
%                                      only if they are among the k nearst
%                                      neighbors of each other. You are
%                                      required to provide the parameter k in
%                                      the options. Default k=5.
%               'Supervised'      -  k = 0
%                                       Put an edge between two nodes if and
%                                       only if they belong to same class. 
%                                    k > 0
%                                       Put an edge between two nodes if
%                                       they belong to same class and they
%                                       are among the k nearst neighbors of
%                                       each other. 
%                                    Default: k=0
%                                   You are required to provide the label
%                                   information gnd in the options.
%                                              
%           WeightMode   -  Indicates how to assign weights for each edge
%                           in the graph. Choices are:
%               'Binary'       - 0-1 weighting. Every edge receiveds weight
%                                of 1. 
%               'HeatKernel'   - If nodes i and j are connected, put weight
%                                W_ij = exp(-norm(x_i - x_j)/2t^2). You are 
%                                required to provide the parameter t. [Default One]
%               'Cosine'       - If nodes i and j are connected, put weight
%                                cosine(x_i,x_j). 
%               
%            k         -   The parameter needed under 'KNN' NeighborMode.
%                          Default will be 5.
%            gnd       -   The parameter needed under 'Supervised'
%                          NeighborMode.  Colunm vector of the label
%                          information for each data point.
%            bLDA      -   0 or 1. Only effective under 'Supervised'
%                          NeighborMode. If 1, the graph will be constructed
%                          to make LPP exactly same as LDA. Default will be
%                          0. 
%            t         -   The parameter needed under 'HeatKernel'
%                          WeightMode. Default will be 1
%         bNormalized  -   0 or 1. Only effective under 'Cosine' WeightMode.
%                          Indicates whether the fea are already be
%                          normalized to 1. Default will be 0
%      bSelfConnected  -   0 or 1. Indicates whether W(i,i) == 1. Default 0
%                          if 'Supervised' NeighborMode & bLDA == 1,
%                          bSelfConnected will always be 1. Default 0.
%            bTrueKNN  -   0 or 1. If 1, will construct a truly kNN graph
%                          (Not symmetric!). Default will be 0. Only valid
%                          for 'KNN' NeighborMode
%
%
%    Examples:
%
%       fea = rand(50,15);
%       options = [];
%       options.NeighborMode = 'KNN';
%       options.k = 5;
%       options.WeightMode = 'HeatKernel';
%       options.t = 1;
%       W = constructW(fea,options);
%       
%       
%       fea = rand(50,15);
%       gnd = [ones(10,1);ones(15,1)*2;ones(10,1)*3;ones(15,1)*4];
%       options = [];
%       options.NeighborMode = 'Supervised';
%       options.gnd = gnd;
%       options.WeightMode = 'HeatKernel';
%       options.t = 1;
%       W = constructW(fea,options);
%       
%       
%       fea = rand(50,15);
%       gnd = [ones(10,1);ones(15,1)*2;ones(10,1)*3;ones(15,1)*4];
%       options = [];
%       options.NeighborMode = 'Supervised';
%       options.gnd = gnd;
%       options.bLDA = 1;
%       W = constructW(fea,options);      
%       
%
%    For more details about the different ways to construct the W, please
%    refer:
%       Deng Cai, Xiaofei He and Jiawei Han, "Document Clustering Using
%       Locality Preserving Indexing" IEEE TKDE, Dec. 2005.
%    
%
%    Written by Deng Cai (dengcai2 AT cs.uiuc.edu), April/2004, Feb/2006,
%                                             May/2007
% 
*/

// 修改自L1WeightMatrix.m

/***************************************************
 * mode name:L1WeightMatrix
 * brief:   coding: UTF-8
 * @author yxt
 * @created 2024/01/23 15:17:50
 * @imfor ~/bigSystem/Emotion/include/L1WeightMatrix.h
 * @modify:利用L1Norm作为度量，构建两个样本之间距离邻接矩阵W
 * 		
***************************************************/


#ifndef __L1WEIGHTMATRIX_H__
#define __L1WEIGHTMATRIX_H__

#ifdef _WIN32
#include <direct.h>

#elif __APPLE__ || __linux__
#include<unistd.h>
// 使用armadillo矩阵库
#include <armadillo>
#endif

#include <string>

namespace L1WM
{

typedef enum {
    KNN = 1,
    Supervised = 2
}NeighborMode_enum;

typedef enum {
    Binary = 1,
    HeatKernel = 2,
    Cosine = 3
}WeightMode_enum;



}
class L1WeightMatrix
{
private:
    std::string metric;
    double PCARatio;
    L1WM::NeighborMode_enum neighborMode;
    int k;
    L1WM::WeightMode_enum weightMode;
    int t;
    arma::vec gnd;

private:
    int bSpeed;
    int bNormalized;
    int bLDA;
    int bSelfConnected;

    int bBinary;
    int bCosine;

private:
    // 邻接矩阵
    // arma::mat W;
    arma::sp_mat W;


public:
    // L1WeightMatrix();
    L1WeightMatrix(arma::mat &fea,
                    std::string metric = std::string(""), double PCARatio = 0.9900, 
                    L1WM::NeighborMode_enum neighborMode = L1WM::KNN, int k = 0,  
                    L1WM::WeightMode_enum weightMode = L1WM::HeatKernel, int t = 1,
                    const arma::vec &gnd = arma::vec()
                    );
    ~L1WeightMatrix();

public:
    arma::sp_mat get_weightMatrix_sp();
    arma::mat get_weightMatrix_full();

    void showPara();
    void L1Dist(arma::mat Data,arma::mat& Distance);


};








#endif
